//
//  MIPData.h
//  V3d_Cocoa
//
//  Created by Y my on 11-4-20.
//  Copyright 2011 NJUST. All rights reserved.
//

#import "ObserverableData.h"
#import "VolDataDelegate.h"
#import "Geometry.h"

//#define _TEST_


#define GET_POSION(x, y, z, pos) (\
((x) = ((pos) >> 22) & 0x000007ff), \
((y) = ((pos) >> 10) & 0x000007ff), \
((z) = (pos) & 0x000003ff))

#define SET_POSION(x, y, z, pos) \
( (pos) = (((x) & 0x000007ff) << 22) | (((y) & 0x000007ff) << 10) | ((z) & 0x000003ff) )

typedef struct tagRawCell
{
	unsigned char Cmax, Cmin;
}RawCell;

typedef struct _Cell
{
	unsigned short Cmax, Cmin;
	unsigned int coord;
}Cell;

typedef struct _Bucket
{
	unsigned short Cmax;
	short unused; // 凑齐8字节
	unsigned int beginIndex;
}Bucket;

@interface MIPData : ObserverableData <VolDataDelegate> {
	unsigned char**** rawData; // 顶点信息
#ifdef _TEST_
	unsigned char* testData;
#endif
	RawCell* rawCells; // 储存每个Cell的Cmax和Cmin
	unsigned char channelCount;
	
	unsigned short x_len, y_len, z_len;
	unsigned short x_cell_len, y_cell_len, z_cell_len;
	
	bool isRedDisplay, isGreenDisplay, isBlueDisplay; // 颜色模式
	
	// 记录每个Cell是否被留下：每个Cell有3条命，每当一个邻居的值大于自己，命减一，减到零或负值时该Cell死亡
	char* isCellAlive;
	
	// 移除无用顶点后，由剩余的Cell生成一个Cell列表，将各个Cell的Cmax，Cmin，以及坐标储存起来，方便排序
	Cell* cells;
	
	// 按4个视角构建4套Cell列表
	unsigned short totalBucketCount[4];// 排序后，Bucket的总个数
	Bucket* sortedBucketInfo[4];  // 还剩的Cell坐标列表的索引，记录了每个Bucket的Cmax以及该Cmax在Cell列表中的起始下标
	unsigned int totalCellCount[4];   // 去除无用Cell后，还剩的Cell的总个数
	unsigned int* sortedCellCoord[4]; // Cell坐标列表，储存Cell在rawData中的坐标。支持的图像最大尺寸为：2048 × 2048 × 1024
}

@property bool isRedDisplay, isGreenDisplay, isBlueDisplay;
@property (readonly) unsigned char channelCount;
@property (readonly) unsigned short x_len, y_len, z_len;
@property (readonly) unsigned short x_cell_len, y_cell_len, z_cell_len;

@property (readonly) unsigned char**** rawData;
#ifdef _TEST_
@property (readonly) unsigned char* testData;
#endif

- (id)initWithRawData:(unsigned char****)data
			 X_LENGTH:(unsigned short)x_length
			 Y_LENGTH:(unsigned short)y_length
			 Z_LENGTH:(unsigned short)z_length
		 ChannelCount:(unsigned char)chanCount;


- (void)proceed;

// 单个Cell投影后，由z值最高的点来确定该使用哪一套Cell列表
- (void)getDataResultByRotationMatrix:(Matrix4*)matRotate
				 out_TotalBucketCount:(unsigned short*)bucketCount
				 out_SortedBucketInfo:(Bucket**)bucketInfos
				   out_TotalCellCount:(unsigned int*)cellCount
				  out_SortedCellCoord:(unsigned int**)cellCoords;

@end
